<script setup lang="tsx">
import { reactive, shallowRef, watch } from 'vue';
import { NModal, type TreeOption } from 'naive-ui';
import { $t } from '@/locales';
import { fetchAddPositionOrg, fetchGetOrgUnitTree, fetchGetPositionOrgIds } from '@/service/api';

defineOptions({
  name: 'PositionOrgAuthModal'
});

interface Props {
  rowData?: Api.SystemManage.Position | null;
}

const props = defineProps<Props>();

const visible = defineModel<boolean>('visible', {
  default: false
});

const title = $t('page.manage.position.setOrgUnit');

const orgTree = shallowRef<TreeOption[]>([]);

const checks = shallowRef<string[]>([]);

const model: Api.SystemManage.PositionOrg = reactive(createDefaultModel());

function createDefaultModel(): Api.SystemManage.PositionOrg {
  return {
    positionId: props.rowData?.id || '',
    orgIds: []
  };
}

async function getOrgTree() {
  const { error, data } = await fetchGetOrgUnitTree();
  if (!error) {
    orgTree.value = data.map(recursive);
  }
}

function recursive(item: Api.SystemManage.OrgUnitTree): TreeOption {
  const result: TreeOption = {
    key: item.id,
    label: item.name
  };
  if (item.children) {
    result.children = item.children.map(recursive);
  }
  return result;
}

async function getOrgIds() {
  const { error, data } = await fetchGetPositionOrgIds(model.positionId);
  if (!error) {
    // 先获取组织树数据
    const { error: treeError, data: treeData } = await fetchGetOrgUnitTree();
    if (!treeError) {
      // 将树数据扁平化以便查找
      const flattenTree = (nodes: TreeOption[]): TreeOption[] => {
        return nodes.reduce((acc, node) => {
          acc.push(node);
          if (node.children) {
            acc.push(...flattenTree(node.children));
          }
          return acc;
        }, [] as TreeOption[]);
      };

      const allOrgKeys = flattenTree(treeData.map(recursive)).map(item => item.key);
      // 过滤掉不在组织树中的数据
      checks.value = data.filter(id => allOrgKeys.includes(id));
      getOrgTree();
    }
  }
}

async function handleSubmit() {
  model.orgIds = checks.value;
  const { error, data } = await fetchAddPositionOrg(model);
  if (!error && data) {
    window.$message?.success?.($t('common.modifySuccess'));
    closeModal();
  }
}

function closeModal() {
  visible.value = false;
}

function init() {
  Object.assign(model, createDefaultModel());
  getOrgIds();
}

watch(visible, val => {
  if (val) {
    init();
  }
});
</script>

<template>
  <NModal v-model:show="visible" :title="title" preset="card" class="w-480px">
    <NTree v-model:checked-keys="checks" :data="orgTree" block-line default-expand-all checkable virtual-scroll class="h-500px" />
    <template #footer>
      <NSpace justify="end">
        <NButton quaternary @click="closeModal">
          {{ $t('common.cancel') }}
        </NButton>
        <NButton type="primary" @click="handleSubmit">
          {{ $t('common.confirm') }}
        </NButton>
      </NSpace>
    </template>
  </NModal>
</template>

<style lang="scss" scoped></style>
